import { instantiate } from 'cc';
import { Button } from 'cc';
import { Sprite } from 'cc';
import { UITransform } from 'cc';
import { Size } from 'cc';
import { Label } from 'cc';
import { SpriteFrame } from 'cc';
import { Vec3 } from 'cc';
import { Prefab } from 'cc';
import { _decorator, Component, Node } from 'cc';
import Config from '../bundle/utils/Config';
import { JsonAsset } from 'cc';
import { Vec2 } from 'cc';
import Design from '../bundle/utils/Design';
const { ccclass, property } = _decorator;

export class AircraftInfo {
    public x: number = -1
    public z: number = -1
    public dir: number = -1
    public covered: boolean = false
    public route: number[] = []
}

export class HangarInfo {
    public x: number = -1
    public z: number = -1
    public loc: Vec2 = new Vec2(-1, -1)
    public aircrafts: AircraftInfo[] = []
}

@ccclass('LevelDesign')
export class LevelDesign extends Component {
    
    @property( {type: Number, displayName: "宽长度" } )
    horizontalSize: number = 7;

    @property( {type: Number, displayName: "高长度" } )
    verticalSize: number = 7;
    
    @property( {type: Number, displayName: "边距" } )
    panelSpace: number = 50;

    @property( {type: Node, displayName: "地板" } )
    baseNode: Node = null;

    @property( {type: Prefab, displayName: "地板砖" } )
    brickPre: Node = null;
    
    @property({ type: [SpriteFrame], displayName: "地板图片" })
    brickFrame: SpriteFrame[] = [];

    @property( {type: Sprite, displayName: "当前选中" } )
    targetSprite: Sprite = null;

    @property( {type: Label, displayName: "当前方向" } )
    curDir: Label = null;

    @property( {type: Label, displayName: "当前选中的地板" } )
    curBrickLabel: Label = null;

    @property( {type: Label, displayName: "是否放置飞机标记" } )
    isAddPlaneLabel: Label = null;

    @property( {type: Label, displayName: "是否放置机库标记" } )
    isAddHangarLabel: Label = null;

    @property( {type: Label, displayName: "是否放置拐点标记" } )
    isAddTurningLabel: Label = null;

    @property( {type: Label, displayName: "定位" } )
    hangarLocLabel: Label = null;

    @property( {type: Prefab, displayName: "飞机预制体" } )
    aircraftPre: Prefab = null;

    @property( {type: Prefab, displayName: "机库预制体" } )
    hangarPre: Prefab = null;

    @property( {type: Prefab, displayName: "拐点预制体" } )
    turningPre: Prefab = null;

    @property( {type: Node, displayName: "机库面板" } )
    hangarNode: Node = null;

    @property( {type: Node, displayName: "选择出库点" } )
    selectOutLoc: Node = null;

    @property( {type: Node, displayName: "机库飞机" } )
    hangarPlanes: Node = null;

    @property( {type: Node, displayName: "机库出库定位" } )
    arrowNode: Node = null;

    @property( {type: JsonAsset, displayName: "关卡" } )
    targetJson: JsonAsset = null;

    @property( {type: String, displayName: "颜色数量" } )
    colorCount: String = "1-1-1-1-1-1-1";

    // 当前地板的标记
    private currentBrick:number = 1
    // 当前方向的标记
    private currentDir: number = 0
    // 选中的定位
    private selectBrick: Node = null
    // 是否放置飞机
    private isAddPlane: boolean = false
    // 是否放置机库
    private isAddHangar: boolean = false
    // 是否放置拐点
    private isAddTurning: boolean = false
    // 是否选择出库点
    private isSelectOut: boolean = false

    private grids: number[][] = []
    private planes: AircraftInfo[] = []
    private hangars: HangarInfo[] = []
    private turnings: Vec2[] = []
    private maps: number[][] = []

    protected start(): void {
        this.drawPanel()
    }

    // 绘制地板
    private drawPanel () {
        this.baseNode.removeAllChildren()

        this.grids = Array.from({ length: this.horizontalSize }, () => Array(this.verticalSize).fill(0));
        this.planes = []
        this.hangars = []

        this.selectBrick = null
        this.curBrickLabel.string = "无"
        
        this.isAddPlane = false
        this.isAddHangar = false
        this.hangarNode.active = false
        this.isAddHangarLabel.string = "否"
        this.isAddPlaneLabel.string = "否"

        for (var ix = 0; ix < this.horizontalSize; ix++) {
            for (var iz = 0; iz < this.verticalSize; iz++) {
                var brick = instantiate( this.brickPre )
                brick.position = new Vec3( ix * this.panelSpace - ((this.horizontalSize - 1) * this.panelSpace * 0.5), (this.verticalSize - 1 - iz) * this.panelSpace - ((this.verticalSize - 1) * this.panelSpace * 0.5) )
                brick.name = ix + "_" + iz
                brick.parent = this.baseNode
                brick.getChildByName("背景").getComponent(UITransform).setContentSize(new Size(this.panelSpace, this.panelSpace,))
                
                const buttonComponent = brick.getChildByName("按钮").addComponent(Button)
                buttonComponent.node.on(Node.EventType.TOUCH_END, () => this.itemClicked(buttonComponent.node.parent))
            }
        }
    }

    // 更新当前的机库信息
    private updateHangar() {
        this.hangarPlanes.removeAllChildren()

        const arr = this.selectBrick.name.split("_")
        const x = parseInt( arr[0] )
        const z = parseInt( arr[1] )

        for (var i = 0; i < this.hangars.length; i++) {
            const hangarDic = this.hangars[i]
            if (hangarDic.x == x && hangarDic.z == z) {            
                if (hangarDic.loc.x == -1 && hangarDic.loc.y == -1) {
                    this.hangarLocLabel.string = "未选"
                    this.arrowNode.active = false
                } else {
                    this.hangarLocLabel.string = "{" + hangarDic.loc.x + ", " + hangarDic.loc.y + "}"
                    this.arrowNode.active = true

                    const newPos = this.baseNode.getChildByName(hangarDic.loc.x + "_" + hangarDic.loc.y).position
                    this.arrowNode.position = new Vec3(newPos.x, newPos.y + this.baseNode.position.y + 35, 0)
                }

                for (var j = 0; j < hangarDic.aircrafts.length; j++) {
                    const aircraftNode = instantiate(this.aircraftPre)
                    aircraftNode.name = j + ""
                    aircraftNode.parent = this.hangarPlanes
                    aircraftNode.position = new Vec3 (j * 50, 0)
    
                    this.updateAircraftRoute(aircraftNode, hangarDic.aircrafts[j])
                }

                return
            }
        }
    }

    // 更新飞机的路线
    private updateAircraftRoute(planeNode: Node, info: AircraftInfo) {
        const planeBody = planeNode.getChildByName("机身")

        if (info.dir == 0) {
            planeBody.angle = 0
        } else if (info.dir == 1) {
            planeBody.angle = 180
        } else if (info.dir == 2) {
            planeBody.angle = 90
        } else if (info.dir == 3) {
            planeBody.angle = 270
        }

        const label = planeNode.getChildByName("Label").getComponent(Label)
        var resultStr = ""
        for (var i = 0; i < info.route.length; i++) {
            const value = info.route[i]
            
            if (value == 1) {
                resultStr = resultStr + "↑"
            } else if (value == 2) {
                resultStr = resultStr + "↓"
            } else if (value == 3) {
                resultStr = resultStr + "←"
            } else if (value == 4) {
                resultStr = resultStr + "→"
            }
        }

        label.string = resultStr

        planeNode.getChildByName("盖布").active = info.covered
    }

    // 获取指定位置的飞机
    private getTargetAircraft() {
        if (this.selectBrick) {
            const arr = this.selectBrick.name.split("_")
            const x = parseInt( arr[0] )
            const z = parseInt( arr[1] )
    
            for (var i = 0; i < this.planes.length; i++) {
                const info = this.planes[i]
                if (info.x == x && info.z == z) {
                    return info
                }
            }
        }

        return null
    }

    // 获取指定位置的机库
    private getTargetHangar() {
        if (this.selectBrick) {
            const arr = this.selectBrick.name.split("_")
            const x = parseInt( arr[0] )
            const z = parseInt( arr[1] )
    
            for (var i = 0; i < this.hangars.length; i++) {
                const info = this.hangars[i]
                if (info.x == x && info.z == z) {
                    return info
                }
            }
        }

        return null
    }

    // 获取指定位置的拐点
    private getTargetTurning() {
        if (this.selectBrick) {
            const arr = this.selectBrick.name.split("_")
            const x = parseInt( arr[0] )
            const z = parseInt( arr[1] )
    
            for (var i = 0; i < this.turnings.length; i++) {
                const info = this.turnings[i]
                if (info.x == x && info.y == z) {
                    return info
                }
            }
        }

        return null
    }

    // ---------------------- 事件 ---------------------- //
    private itemClicked(sender: Node) {
        const arr = sender.name.split("_")
        const x = parseInt( arr[0] )
        const z = parseInt( arr[1] )

        if (this.isSelectOut) {
            this.hangarLocLabel.string = "{" + x + ", " + z + "}"

            const arr = this.selectBrick.name.split("_")
            const ix = parseInt( arr[0] )
            const iz = parseInt( arr[1] )

            for (var i = 0; i < this.hangars.length; i++) {
                const hangarDic = this.hangars[i]
                if (hangarDic.x == ix && hangarDic.z == iz) {
                    hangarDic.loc = new Vec2(x, z)
                }
            }
            
            this.isSelectOut = false
            this.updateHangar()
        } else {
            if (this.isAddPlane == false && this.isAddHangar == false && this.isAddTurning == false) {
                
                const brickSprite = sender.getChildByName("背景").getComponent(Sprite)
                brickSprite.spriteFrame = this.brickFrame[this.currentBrick - 1]
                
                if (this.currentDir == 0) {
                    brickSprite.node.angle = 0
                } else if (this.currentDir == 1) {
                    brickSprite.node.angle = 180
                } else if (this.currentDir == 2) {
                    brickSprite.node.angle = 90
                } else if (this.currentDir == 3) {
                    brickSprite.node.angle = 270
                }
        
                this.selectBrick = sender
                this.curBrickLabel.string = this.selectBrick.name
        
                this.grids[x][z] = this.currentDir * 100 + this.currentBrick * 10
            } else {
                if (this.isAddPlane == true) {
                    if (sender.getChildByName("飞机") == null) {
                        const aircraftNode = instantiate(this.aircraftPre)
                        aircraftNode.name = "飞机"
                        aircraftNode.parent = sender
        
                        const planeDic = new AircraftInfo()
                        planeDic.x = x
                        planeDic.z = z
                        planeDic.dir = this.currentDir

                        this.updateAircraftRoute(aircraftNode, planeDic)
                        
                        this.planes.push(planeDic)
                    }
            
                    this.selectBrick = sender
                    this.curBrickLabel.string = this.selectBrick.name
                }
    
                if (this.isAddHangar == true) {
                    if (sender.getChildByName("机库") == null) {
                        const hangarNode = instantiate(this.hangarPre)
                        hangarNode.name = "机库"
                        hangarNode.parent = sender
        
                        const hangarDic = new HangarInfo()
                        hangarDic.x = x
                        hangarDic.z = z

                        this.hangars.push(hangarDic)
                    }
            
                    this.selectBrick = sender
                    this.curBrickLabel.string = this.selectBrick.name
                    this.updateHangar()
                }
                
                if (this.isAddTurning == true) {
                    if (sender.getChildByName("拐点") == null) {
                        const turningNode = instantiate(this.turningPre)
                        turningNode.name = "拐点"
                        turningNode.parent = sender
                        
                        this.turnings.push(new Vec2(x, z))
                    }
            
                    this.selectBrick = sender
                    this.curBrickLabel.string = this.selectBrick.name
                }
            }
        }
    }

    // 点击选择地板
    private selectBrickClicked(event, customEventData) {
        const targetSprite = event.target.getComponent(Sprite)
        this.targetSprite.spriteFrame = targetSprite.spriteFrame
        this.currentBrick = parseInt( customEventData )
    }

    // 切换方向
    private changeDir() {
        if (this.currentDir == 0) {
            this.currentDir = 1
            this.curDir.string = "下"

            this.targetSprite.node.angle = 180
        } else if (this.currentDir == 1) {
            this.currentDir = 2
            this.curDir.string = "左"

            this.targetSprite.node.angle = 90
        } else if (this.currentDir == 2) {
            this.currentDir = 3
            this.curDir.string = "右"

            this.targetSprite.node.angle = 270
        } else if (this.currentDir == 3) {
            this.currentDir = 0
            this.curDir.string = "上"

            this.targetSprite.node.angle = 0
        }
    }

    // 移除
    private removeClicked() {
        if (this.isAddPlane == false && this.isAddHangar == false && this.isAddTurning == false) {
            const brickSprite = this.selectBrick.getChildByName("背景").getComponent(Sprite)
            brickSprite.spriteFrame = null
            
            const arr = this.selectBrick.name.split("_")
            const x = parseInt( arr[0] )
            const z = parseInt( arr[1] )
    
            this.grids[x][z] = 0
        } else {
            if (this.isAddPlane) {
                if (this.selectBrick && this.selectBrick.getChildByName("飞机") != null) {
                    this.selectBrick.removeAllChildren()

                    const info = this.getTargetAircraft()
                    if (info != null) {
                        Config.removeFromArray(this.planes, [info])
                    }
                }
            }

            if (this.isAddHangar) {
                if (this.selectBrick && this.selectBrick.getChildByName("机库") != null) {
                    this.selectBrick.removeAllChildren()

                    const info = this.getTargetHangar()
                    if (info != null) {
                        Config.removeFromArray(this.hangars, [info])
                        this.hangarNode.active = false
                    }
                }
            }

            if (this.isAddTurning) {
                if (this.selectBrick && this.selectBrick.getChildByName("拐点") != null) {
                    this.selectBrick.removeAllChildren()

                    const info = this.getTargetTurning()
                    if (info != null) {
                        Config.removeFromArray(this.turnings, [info])
                        this.hangarNode.active = false
                    }
                }
            }
        }
    }

    // 导出
    private deriveClicked() {
        const arr = this.colorCount.split("-")
        var allCount = 0
        for (var i = 0; i < arr.length; i++) {
            allCount += parseInt(arr[i])
        }

        if (allCount != this.planes.length) {
            console.error("警告: 颜色数量和飞机数量对不上")
            console.error("颜色数量 = " + allCount + ", 飞机数量 = " + this.planes.length)
        }

        const result = { bricks: this.grids, planes: this.planes, hangars: this.hangars, colors: arr }
        console.log (JSON.stringify(result))
    }

    // 重置
    private resetClicked() {
        this.drawPanel()
    }

    // 读取
    private readClicked() {
        this.drawPanel()

        const bricks = this.targetJson.json["bricks"]
        const planes = this.targetJson.json["planes"]
        const hangars = this.targetJson.json["hangars"]
        
        for (var ix = 0; ix < bricks.length; ix++) {
            for (var iz = 0; iz < bricks[ix].length; iz++) {
                const value = bricks[ix][iz]
                if (value != 0) {
                    
                    const dir = Math.floor( value / 100 )
                    const grid = Math.floor((value % 100) / 10) - 1
                    

                    
                    const brickSprite = this.baseNode.getChildByName(ix + "_" + iz).getChildByName("背景").getComponent(Sprite)
                    brickSprite.spriteFrame = this.brickFrame[grid]

                    if (dir == 0) {
                        brickSprite.node.angle = 0
                    } else if (dir == 1) {
                        brickSprite.node.angle = 180
                    } else if (dir == 2) {
                        brickSprite.node.angle = 90
                    } else if (dir == 3) {
                        brickSprite.node.angle = 270
                    }
                }

                this.grids[ix][iz] = value
            }
        }

        for (var i = 0; i < planes.length; i++) {
            const planeDic = planes[i]

            const aircraftNode = instantiate(this.aircraftPre)
            aircraftNode.name = "飞机"
            aircraftNode.parent = this.baseNode.getChildByName(planeDic.x + "_" + planeDic.z)

            this.updateAircraftRoute(aircraftNode, planeDic)
            this.planes.push(planeDic)
        }

        for (var i = 0; i < hangars.length; i++) {
            const hangerDic = hangars[i]

            const hangarNode = instantiate(this.hangarPre)
            hangarNode.name = "机库"
            hangarNode.parent = this.baseNode.getChildByName(hangerDic.x + "_" + hangerDic.z)

            this.hangars.push(hangerDic)
        }
    }

    // 添加飞机
    private addAircraft(event) {
        this.isAddPlane = !this.isAddPlane
        if (this.isAddPlane) {
            this.isAddHangar = false
            this.isAddTurning = false

            this.isAddHangarLabel.string = "否"
            this.isAddPlaneLabel.string = "是"
            this.isAddTurningLabel.string = "否"

            this.hangarNode.active = false
        } else {
            this.isAddPlaneLabel.string = "否"
        }
    }

    // 设置飞机方向
    private planeDirClicked(event, customEventData) {
        const value = parseInt(customEventData)

        if (this.isAddHangar) {
            const arr = this.selectBrick.name.split("_")
            const x = parseInt( arr[0] )
            const z = parseInt( arr[1] )

            for (var i = 0; i < this.hangars.length; i++) {
                const hangarDic = this.hangars[i]
                if (hangarDic.x == x && hangarDic.z == z) {
                    if (hangarDic.aircrafts.length > 0) {
                        hangarDic.aircrafts[hangarDic.aircrafts.length - 1].route.push(value)
                        this.updateAircraftRoute(this.hangarPlanes.getChildByName((hangarDic.aircrafts.length - 1).toString()), hangarDic.aircrafts[hangarDic.aircrafts.length - 1])
                    }
                }
            }
        } else {
            if (this.selectBrick && this.selectBrick.getChildByName("飞机") != null) {
                const aircraftInfo = this.getTargetAircraft()
                if (aircraftInfo != null) {
                    aircraftInfo.route.push(value)
                    this.updateAircraftRoute(this.selectBrick.getChildByName("飞机"), aircraftInfo)
                }
            }
        }
    }

    // 盖布
    private coverClothClicked() {
        if (this.isAddHangar == false) {
            if (this.selectBrick && this.selectBrick.getChildByName("飞机") != null) {
                const aircraftInfo = this.getTargetAircraft()
                if (aircraftInfo != null) {
                    aircraftInfo.covered = !aircraftInfo.covered
                    this.updateAircraftRoute(this.selectBrick.getChildByName("飞机"), aircraftInfo)
                }
            }
        }
    }

    // 添加机库
    private addHangar(event) {
        this.isAddHangar = !this.isAddHangar
        if (this.isAddHangar) {
            this.isAddPlane = false
            this.isAddTurning = false

            this.isAddHangarLabel.string = "是"
            this.isAddPlaneLabel.string = "否"
            this.isAddTurningLabel.string = "否"
            this.hangarNode.active = true
        } else {
            this.isAddHangarLabel.string = "否"
            this.hangarNode.active = false
        }
    }

    // 选择一个出库点
    private selectOutPoint() {
        if (this.isSelectOut == false) {
            this.isSelectOut = true
        }
    }

    // 添加机库飞机
    private addHangarPlane() {
        const arr = this.selectBrick.name.split("_")
        const x = parseInt( arr[0] )
        const z = parseInt( arr[1] )

        for (var i = 0; i < this.hangars.length; i++) {
            const hangarDic = this.hangars[i]
            if (hangarDic.x == x && hangarDic.z == z) {
                const aircraftNode = instantiate (this.aircraftPre)
                aircraftNode.parent = this.hangarPlanes
                aircraftNode.position = new Vec3 (hangarDic.aircrafts.length * 50, 0)
                aircraftNode.name = hangarDic.aircrafts.length + ""

                const planeDic = new AircraftInfo()
                planeDic.dir = this.currentDir

                this.updateAircraftRoute(aircraftNode, planeDic)

                hangarDic.aircrafts.push(planeDic)
            }
        }
    }

    // 添加拐点
    private addTurningPoint() {

        this.isAddTurning = !this.isAddTurning
        if (this.isAddTurning) {
            this.isAddHangar = false
            this.isAddPlane = false

            this.isAddHangarLabel.string = "否"
            this.isAddPlaneLabel.string = "否"
            this.isAddTurningLabel.string = "是"
            
            this.hangarNode.active = false
        } else {
            this.isAddTurningLabel.string = "否"
        }
    }
}


